package cn.iocoder.yudao.module.ym.service.sitedata;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Pair;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO;
import cn.iocoder.yudao.module.ym.controller.admin.site.vo.SiteImportVO;
import cn.iocoder.yudao.module.ym.controller.admin.site.vo.SitePageReqVO;
import cn.iocoder.yudao.module.ym.controller.admin.site.vo.SiteRespVO;
import cn.iocoder.yudao.module.ym.controller.admin.sitedata.ListConverter;
import cn.iocoder.yudao.module.ym.controller.admin.ticket.vo.TicketPageReqVO;
import cn.iocoder.yudao.module.ym.controller.admin.ticket.vo.TicketRespVO;
import cn.iocoder.yudao.module.ym.dal.dataobject.area.AreaDO;
import cn.iocoder.yudao.module.ym.dal.dataobject.site.SiteDO;
import cn.iocoder.yudao.module.ym.dal.dataobject.ticket.TicketDO;
import cn.iocoder.yudao.module.ym.dal.mysql.area.AreaMapper;
import cn.iocoder.yudao.module.ym.dal.mysql.site.SiteMapper;
import cn.iocoder.yudao.module.ym.dal.mysql.ticket.TicketMapper;
import cn.iocoder.yudao.module.ym.service.site.SiteService;
import cn.iocoder.yudao.module.ym.service.ticket.TicketService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import cn.iocoder.yudao.module.ym.controller.admin.sitedata.vo.*;
import cn.iocoder.yudao.module.ym.dal.dataobject.sitedata.SiteDataDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.ym.dal.mysql.sitedata.SiteDataMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.infra.enums.TicketStatusEnum.PENDING;

/**
 * 电站数据 Service 实现类
 *
 * @author 韩艳阳
 */
@Service
@Validated
public class SiteDataServiceImpl implements SiteDataService {

    @Resource
    private SiteDataMapper siteDataMapper;

    @Resource
    private SiteMapper siteMapper;

    @Resource
    private SiteService siteService;

    @Resource
    private AreaMapper areaMapper;

    @Resource
    private TicketService ticketService;

    @Resource
    private TicketMapper ticketMapper;



    @Override
    public Long createSiteData(SiteDataSaveReqVO createReqVO) {
        // 插入
        SiteDataDO siteData = BeanUtils.toBean(createReqVO, SiteDataDO.class);
        siteDataMapper.insert(siteData);
        // 返回
        return siteData.getId();
    }

    @Override
    public void updateSiteData(SiteDataSaveReqVO updateReqVO) {
        // 校验存在
        validateSiteDataExists(updateReqVO.getId());
        // 更新
        SiteDataDO updateObj = BeanUtils.toBean(updateReqVO, SiteDataDO.class);
        siteDataMapper.updateById(updateObj);
    }

    @Override
    public void deleteSiteData(Long id) {
        // 校验存在
        validateSiteDataExists(id);
        // 删除
        siteDataMapper.deleteById(id);
    }

    private void validateSiteDataExists(Long id) {
        if (siteDataMapper.selectById(id) == null) {
            throw exception(SITE_DATA_NOT_EXISTS);
        }
    }

    @Override
    public SiteDataDO getSiteData(Long id) {
        return siteDataMapper.selectById(id);
    }

    @Override
    public List<SiteDataDO> getSiteDataList(SiteDataPageReqVO pageReqVO) {
        return siteDataMapper.selectList(pageReqVO);
    }

    @Override
    public PageResult<SiteDataDO> getSiteDataPage(SiteDataPageReqVO pageReqVO) {
        PageResult<SiteDataDO> siteDataDOPageResult = siteDataMapper.selectPage(pageReqVO);
        List<SiteDataDO> siteDataDOList = siteDataDOPageResult.getList();

        List<SiteDO> siteDOList = siteMapper.selectList();

        Map<Long,String> siteNameMap = Optional.ofNullable(siteDOList)
                .orElseGet(Collections::emptyList)
                .stream()
                .filter(siteDO -> siteDO.getSiteName() != null)
                .collect(Collectors.toMap(SiteDO::getId,SiteDO::getSiteName,(oldValue, newValue) -> oldValue));

        for (SiteDataDO siteDataDO : siteDataDOList) {
            Long siteId = siteDataDO.getSiteId();
            siteDataDO.setSiteName(siteNameMap.get(siteId));
        }
        return siteDataDOPageResult;
    }
    @Override
    public UserImportRespVO importSiteDate(List<SiteDataImportVO> importVOList, Boolean updateSupport){
        //导入数据是否为空
        if (CollUtil.isEmpty(importVOList)) {
            throw exception(SITE_DATA_IMPORT_LIST_IS_EMPTY);
        }


        //处理导入逻辑
        UserImportRespVO respVO = UserImportRespVO.builder()
                .createUsernames(new ArrayList<>())
                .updateUsernames(new ArrayList<>())
                .failureUsernames(new LinkedHashMap<>()).build();

        List<SiteDO> siteDOS = siteMapper.selectList();

        //Map<站名，电站DO类>
        Map<String,SiteDO> siteMap = Optional.ofNullable(siteDOS)
                .orElseGet(Collections::emptyList)
                .stream()
                .filter(siteDO -> siteDO.getSiteName() != null)
                .collect(Collectors.toMap(
                        SiteDO::getSiteName,
                        Function.identity(),
                        (oldValue, newValue) -> oldValue
                ));
        //获取电站id，并set进相对应电站VO
        List<SiteDataImportVO> siteDataImportVOList = new ArrayList<>();
        for (SiteDataImportVO vo : importVOList) {
            String siteName = vo.getSiteName();
            SiteDO siteDO = siteMap.get(siteName);
            if (siteDO == null) {
                respVO.getFailureUsernames().put(siteName, "系统暂无该电站");
                continue;
            }
            vo.setSiteId(siteDO.getId());
            siteDataImportVOList.add(vo);
        }

        Map<String, Integer> stringIntegerMap = checkUniqueCombination(siteDataImportVOList);



        //定义一个新的Map用来存储以id年月为key的DO数据
        Map<String,SiteDataDO> allSiteDataMaps = new HashMap<>();

        List<SiteDataDO> siteDataList = siteDataMapper.selectList();
        for (SiteDataDO vo : siteDataList) {
            allSiteDataMaps.put(vo.getSiteId() + "_" + vo.getYear() + "_" + vo.getMonth(),vo);
        }



        // 6. 处理有效VO
        List<SiteDataDO> insertList = new ArrayList<>();
        List<SiteDataDO> updateList = new ArrayList<>();
        //定义BigDecimal类型的0
        BigDecimal zero = new BigDecimal(BigInteger.ZERO);
        for (SiteDataImportVO vo : siteDataImportVOList) {

            String key1 = vo.getSiteId() + "_" + vo.getYear() + "_" + vo.getMonth();
            String key2 = vo.getSiteName() + "_" + vo.getYear() + "_" + vo.getMonth();
            Integer i = stringIntegerMap.get(key1);
            if(i > 1){
                respVO.getFailureUsernames().put(key2, "表格数据重复");
                continue;
            }

            SiteDataDO existingData = allSiteDataMaps.get(key1);

            if (existingData == null) {
                // 插入新记录
                insertList.add(BeanUtil.toBean(vo, SiteDataDO.class));
                respVO.getCreateUsernames().add(vo.getSiteName());
            } else if (Boolean.TRUE.equals(updateSupport)) {
                // 更新记录（需保留原ID）
                SiteDataDO updateData = BeanUtil.toBean(vo, SiteDataDO.class);
                updateData.setId(existingData.getId());
                updateList.add(updateData);
                respVO.getUpdateUsernames().add(vo.getSiteName());
            } else {
                respVO.getFailureUsernames().put(key2, "电站数据已存在且不允许更新");
            }
        }

        // 7. 批量数据库操作
        if (CollUtil.isNotEmpty(insertList)) {
            siteDataMapper.insertBatch(insertList, 5000);
        }
        if (CollUtil.isNotEmpty(updateList)) {
            siteDataMapper.updateBatch(updateList, 5000);
        }
        return respVO;
    }

    /**
     * 判断三个字段的组合是否在列表中唯一
     * @param importVOList 数据列表
     * @return 每个元素对应的唯一性结果（true表示唯一）
     */
    public static Map<String, Integer>  checkUniqueCombination(List<SiteDataImportVO> importVOList) {


        // 1. 构建复合键并统计频率
        Map<String, Integer> keyCountMap = new HashMap<>();
        for (SiteDataImportVO vo : importVOList) {
            String key = vo.getSiteId() + "_" + vo.getYear() + "_" + vo.getMonth();
            keyCountMap.merge(key, 1, Integer::sum);

        }
        return keyCountMap;
    }

    //获取初步筛选后值
    @Override
    public List<SiteDataPageReqVO> sumList(SiteDataPageReqVO reqVO){
        LambdaQueryWrapper<SiteDataDO> siteDataDOLambdaQueryWrapper = siteDataMapper.sumList(reqVO);
        List<Long> siteIdList = reqVO.getSiteIdList();
        List<Long> areaIdList = reqVO.getAreaIdList();
        Long userId= reqVO.getUserId();


        if (siteIdList != null && !siteIdList.isEmpty()){
            siteDataDOLambdaQueryWrapper.in(SiteDataDO::getSiteId, siteIdList);

        }else if (areaIdList != null && !areaIdList.isEmpty()) {

            SitePageReqVO sitePageReqVO = new SitePageReqVO();
            sitePageReqVO.setAreaIdList(areaIdList);
            List<SiteRespVO> siteList = siteService.getSiteList(sitePageReqVO);
            Set<Long> siteIdSet = siteList.stream()
                    .map(SiteRespVO::getId)
                    .collect(Collectors.toSet());
            if (!siteIdSet.isEmpty()) {
                siteDataDOLambdaQueryWrapper.in(SiteDataDO::getSiteId, siteIdSet);
            }
        }else if(userId != null){

            // 1.先获取到这些人绑定的站点
            SitePageReqVO sitePageReqVO = new SitePageReqVO();
            sitePageReqVO.setUserId(userId);
            List<SiteRespVO> siteList = siteService.getSiteList(sitePageReqVO);
            Set<Long> siteIdSet = siteList.stream()
                    .map(SiteRespVO::getId)
                    .collect(Collectors.toSet());
            if (!siteIdSet.isEmpty()) {
                siteDataDOLambdaQueryWrapper.in(SiteDataDO::getSiteId, siteIdSet);
            }
        }


        if (reqVO.getYearList() != null && !reqVO.getYearList().isEmpty()){
            siteDataDOLambdaQueryWrapper.in(SiteDataDO::getYear,reqVO.getYearList());
        }

        //获取筛选后的电站数据
        List<SiteDataDO> siteDataDOList = siteDataMapper.selectList(siteDataDOLambdaQueryWrapper);


        return calculateSummary(siteDataDOList);
    }


    //生成Map来保存累加之后的数据
    public List<SiteDataPageReqVO> calculateSummary(List<SiteDataDO> dataList) {
        // 1. 初始化月度统计容器（1-12月）
        Map<Integer, SiteDataPageReqVO> monthlyStats = IntStream.rangeClosed(1, 12)
                .boxed()
                .collect(Collectors.toMap(
                        month -> month,
                        month -> {
                            SiteDataPageReqVO vo = new SiteDataPageReqVO();
                            vo.setMonth(month);  // 确保VO有month字段
                            initZeroValues(vo);  // 初始化所有数值字段为0
                            return vo;
                        }
                ));

        //获取月份出现的次数
        Map<Integer, Long> monthCountMap = dataList.stream()
                .filter(d -> d.getMonth() != null && d.getMonth() >= 1 && d.getMonth() <= 12)
                .collect(Collectors.groupingBy(data -> data.getMonth(), Collectors.counting()));

        // 2. 按月份分组统计
        dataList.stream()
                .filter(d -> d.getMonth() != null && d.getMonth() >= 1 && d.getMonth() <= 12)
                .forEach(data -> {
                    SiteDataPageReqVO monthly = monthlyStats.get(data.getMonth());
                    accumulate(monthly, data);
                });

        //之前每月求和后的快慢运能除以这些数据每月出现的次数
        for (int i = 1;i <= 12;i++)
        {
            SiteDataPageReqVO vo = monthlyStats.get(i);
            Long counts = monthCountMap.get(i);
            if (counts != null && !counts.equals(0)) {
                vo.setSlowCapacity(vo.getSlowCapacity().divide(BigDecimal.valueOf(counts),2,RoundingMode.HALF_UP));
                vo.setFastCapacity(vo.getFastCapacity().divide(BigDecimal.valueOf(counts),2,RoundingMode.HALF_UP));
            }else {
                vo.setSlowCapacity(BigDecimal.ZERO);
                vo.setFastCapacity(BigDecimal.ZERO);
            }
        }



        // 3. 计算年度总和（第13月）
        SiteDataPageReqVO annual = new SiteDataPageReqVO();
        annual.setMonth(13);  // 用13表示全年
        initZeroValues(annual);

        monthlyStats.values().forEach(monthly -> accumulate(annual, monthly));



        // 4. 合并结果
        List<SiteDataPageReqVO> result = new ArrayList<>(monthlyStats.values());
        result.add(annual);

        //年份总和除以12个月。

//        annual.setSlowCapacity(annual.getSlowCapacity().divide(BigDecimal.valueOf(12),2,RoundingMode.HALF_UP));
//        annual.setFastCapacity(annual.getFastCapacity().divide(BigDecimal.valueOf(12),2,RoundingMode.HALF_UP));

        for (SiteDataPageReqVO vo : result) {
            if (vo.getRatedPower().compareTo(BigDecimal.ZERO) != 0) {
                vo.setPowerUtilization(vo.getElectricQuantity().divide(vo.getRatedPower(),4,RoundingMode.HALF_UP));
            }else {
                vo.setPowerUtilization(BigDecimal.ZERO);
            }

            if(vo.getElecCost().compareTo(BigDecimal.ZERO) != 0){
                vo.setLossRate(vo.getPowerLoss().divide(vo.getElecCost(),4,RoundingMode.HALF_UP));
            }else {
                vo.setLossRate(BigDecimal.ZERO);
            }

            if (vo.getMonth().equals(13)) {

                vo.setSlowCapacity(vo.getSlowCapacity().divide(BigDecimal.valueOf(12),2,RoundingMode.HALF_UP));
                vo.setFastCapacity(vo.getFastCapacity().divide(BigDecimal.valueOf(12),2,RoundingMode.HALF_UP));

            }

        }

        result.stream()
                .sorted(Comparator.comparingInt(SiteDataPageReqVO::getMonth))
                .collect(Collectors.toList());


        return result;
    }





    // 初始化数值字段为0
    private void initZeroValues(SiteDataPageReqVO vo) {
        vo.setElectricQuantity(BigDecimal.ZERO);          // 电量
        vo.setFastChargeQuantity(BigDecimal.ZERO);        // 快充电量
        vo.setSlowChargeQuantity(BigDecimal.ZERO);        // 慢充电量
        vo.setRatedPower(BigDecimal.ZERO);                // 额定功率电量
        vo.setPowerUtilization(BigDecimal.ZERO);          // 功率利用率
        vo.setCommPower(BigDecimal.ZERO);                 // 投运功率
        vo.setPfFee(BigDecimal.ZERO);                      // 力调电费
        vo.setElecCost(BigDecimal.ZERO);                   // 电费成本
        vo.setPowerLoss(BigDecimal.ZERO);                  // 电损
        vo.setLossRate(BigDecimal.ZERO);                   // 电损率
        vo.setDeprec(BigDecimal.ZERO);                     // 折旧
        vo.setOpCostShare(BigDecimal.ZERO);                // 运营成本-分成
        vo.setOpCostRent(BigDecimal.ZERO);                 // 运营成本-租金
        vo.setOpCostOther(BigDecimal.ZERO);                // 运营成本-其他
        vo.setOpCostLabor(BigDecimal.ZERO);                // 运营成本-人工
        vo.setOpCostFacility(BigDecimal.ZERO);             // 运营成本-运营设施
        vo.setMaintCost(BigDecimal.ZERO);                  // 运维成本
        vo.setOpCostAll(BigDecimal.ZERO);                  // 运营成本合计
        vo.setElecRev(BigDecimal.ZERO);                     // 电费收入
        vo.setEdDiscount(BigDecimal.ZERO);                 // ED客户充电折扣
        vo.setServFeeRev(BigDecimal.ZERO);                 // 服务费收入
        vo.setValueAddServ(BigDecimal.ZERO);               // 增值服务
        vo.setCompServRev(BigDecimal.ZERO);                // 综合服务费收入
        vo.setSelfOpGp(BigDecimal.ZERO);                   // 自营充电毛利
        vo.setOtherRev(BigDecimal.ZERO);                   // 其它业务收入
        vo.setOtherCost(BigDecimal.ZERO);                   // 其它业务成本
        vo.setSelfOpAll(BigDecimal.ZERO);                   // 自营总收益
    }

    // 累加数据
    private void accumulate(SiteDataPageReqVO target, SiteDataDO source) {
        // 基础电量字段累加
        target.setElectricQuantity(add(target.getElectricQuantity(), source.getElectricQuantity()));
        target.setFastChargeQuantity(add(target.getFastChargeQuantity(), source.getFastChargeQuantity()));
        target.setSlowChargeQuantity(add(target.getSlowChargeQuantity(), source.getSlowChargeQuantity()));

        // 功率相关字段累加（为后续计算 powerUtilization 准备）
        target.setRatedPower(add(target.getRatedPower(), source.getRatedPower()));  // 额定功率总和

        // 运营成本字段累加
        target.setCommPower(add(target.getCommPower(), source.getCommPower()));
        target.setPfFee(add(target.getPfFee(), source.getPfFee()));
        target.setElecCost(add(target.getElecCost(), source.getElecCost()));
        target.setPowerLoss(add(target.getPowerLoss(), source.getPowerLoss()));
        target.setDeprec(add(target.getDeprec(), source.getDeprec()));
        target.setOpCostShare(add(target.getOpCostShare(), source.getOpCostShare()));
        target.setOpCostRent(add(target.getOpCostRent(), source.getOpCostRent()));
        target.setOpCostOther(add(target.getOpCostOther(), source.getOpCostOther()));
        target.setOpCostLabor(add(target.getOpCostLabor(), source.getOpCostLabor()));
        target.setOpCostFacility(add(target.getOpCostFacility(), source.getOpCostFacility()));
        target.setMaintCost(add(target.getMaintCost(), source.getMaintCost()));
        target.setOpCostAll(add(target.getOpCostAll(), source.getOpCostAll()));

        // 收入相关字段累加（为后续计算 lossRate 准备）
        target.setElecRev(add(target.getElecRev(), source.getElecRev()));
        target.setEdDiscount(add(target.getEdDiscount(), source.getEdDiscount()));
        target.setServFeeRev(add(target.getServFeeRev(), source.getServFeeRev()));
        target.setValueAddServ(add(target.getValueAddServ(), source.getValueAddServ()));
        target.setCompServRev(add(target.getCompServRev(), source.getCompServRev()));
        target.setSelfOpGp(add(target.getSelfOpGp(), source.getSelfOpGp()));
        target.setOtherRev(add(target.getOtherRev(), source.getOtherRev()));
        target.setOtherCost(add(target.getOtherCost(), source.getOtherCost()));
        target.setSelfOpAll(add(target.getSelfOpAll(), source.getSelfOpAll()));
        target.setSlowCapacity(add(target.getSlowCapacity(),source.getSlowCapacity()));
        target.setFastCapacity(add(target.getFastCapacity(),source.getFastCapacity()));
    }

    private void accumulate(SiteDataPageReqVO target, SiteDataPageReqVO source) {
        // 基础电量字段累加
        target.setElectricQuantity(add(target.getElectricQuantity(), source.getElectricQuantity()));
        target.setFastChargeQuantity(add(target.getFastChargeQuantity(), source.getFastChargeQuantity()));
        target.setSlowChargeQuantity(add(target.getSlowChargeQuantity(), source.getSlowChargeQuantity()));

        // 功率相关字段累加（为后续计算 powerUtilization 准备）
        target.setRatedPower(add(target.getRatedPower(), source.getRatedPower()));  // 额定功率总和

        // 运营成本字段累加
        target.setCommPower(add(target.getCommPower(), source.getCommPower()));
        target.setPfFee(add(target.getPfFee(), source.getPfFee()));
        target.setElecCost(add(target.getElecCost(), source.getElecCost()));
        target.setPowerLoss(add(target.getPowerLoss(), source.getPowerLoss()));
        target.setDeprec(add(target.getDeprec(), source.getDeprec()));
        target.setOpCostShare(add(target.getOpCostShare(), source.getOpCostShare()));
        target.setOpCostRent(add(target.getOpCostRent(), source.getOpCostRent()));
        target.setOpCostOther(add(target.getOpCostOther(), source.getOpCostOther()));
        target.setOpCostLabor(add(target.getOpCostLabor(), source.getOpCostLabor()));
        target.setOpCostFacility(add(target.getOpCostFacility(), source.getOpCostFacility()));
        target.setMaintCost(add(target.getMaintCost(), source.getMaintCost()));
        target.setOpCostAll(add(target.getOpCostAll(), source.getOpCostAll()));

        // 收入相关字段累加（为后续计算 lossRate 准备）
        target.setElecRev(add(target.getElecRev(), source.getElecRev()));
        target.setEdDiscount(add(target.getEdDiscount(), source.getEdDiscount()));
        target.setServFeeRev(add(target.getServFeeRev(), source.getServFeeRev()));
        target.setValueAddServ(add(target.getValueAddServ(), source.getValueAddServ()));
        target.setCompServRev(add(target.getCompServRev(), source.getCompServRev()));
        target.setSelfOpGp(add(target.getSelfOpGp(), source.getSelfOpGp()));
        target.setOtherRev(add(target.getOtherRev(), source.getOtherRev()));
        target.setOtherCost(add(target.getOtherCost(), source.getOtherCost()));
        target.setSelfOpAll(add(target.getSelfOpAll(), source.getSelfOpAll()));
        target.setSlowCapacity(add(target.getSlowCapacity(),source.getSlowCapacity()));
        target.setFastCapacity(add(target.getFastCapacity(),source.getFastCapacity()));
    }


    //加法
    private BigDecimal add(BigDecimal a, BigDecimal b) {
        if (a == null) a = BigDecimal.ZERO;
        if (b == null) b = BigDecimal.ZERO;
        return a.add(b);
    }


    //获取上个月的图表数据
    @Override
    public SiteDataPageReqVO chartData(SitePageReqVO pageReqVO){
        //根据权限获取用户能看见的所有电站
        List<SiteRespVO> siteList = siteService.getSiteList(pageReqVO);
        //获取电站id
        List<Long> siteIds = new ArrayList<>();
        if (siteList != null && !siteList.isEmpty()) {
            for (SiteRespVO vo : siteList) {
                Long id = vo.getId();
                siteIds.add(id);
            }
        }
        //获取电站下的所有财务数据
        List<SiteDataDO> siteDataDOList = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .in(SiteDataDO::getSiteId,siteIds));

        LocalDate localDate = LocalDate.now();
        //获取今年上个月的数据
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        int lastMonth = 0;
        int lastYear = 0;
        if (month == 1) {
            year = localDate.getYear() - 1;
            lastMonth = 12;
        }else {
            lastMonth = month - 1;
        }
        List<SiteDataDO> lastMonthAllData = new ArrayList<>();
        for (SiteDataDO siteDataDO : siteDataDOList) {
            if (siteDataDO.getYear() == lastYear && siteDataDO.getMonth() == lastMonth) {
                lastMonthAllData.add(siteDataDO);
            }
        }

        List<SiteDataPageReqVO> siteDataPageReqVOS = calculateSummary(lastMonthAllData);


        Map<Integer,SiteDataPageReqVO> voMap = siteDataPageReqVOS.stream()
                .collect(Collectors.toMap(
                        SiteDataPageReqVO::getMonth,
                        Function.identity(),
                        (oldVO,newVO) ->oldVO
                ));

        SiteDataPageReqVO vo = voMap.get(lastMonth);

        return vo;
    }



    //获取上月运能以及上月运能和上上月运能的百分比
    @Override
    public Map<Object,Object> averageCapacity(SitePageReqVO sitePageReqVO){
        //获取到用户能看到的电站ids
        Map<Object,Object> map = new HashMap<>();
        List<SiteRespVO> siteList = siteService.getSiteList(sitePageReqVO);
        if (siteList == null || siteList.isEmpty()) {
            return null;
        }

        List<Long> siteIds = siteList.stream().map(SiteRespVO::getId).collect(Collectors.toList());
      /*  //获取这些电站的上月数据，2025年5月获取到2025年4月
        List<SiteDataDO> siteDataDOList1 = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .in(SiteDataDO::getSiteId,siteIds)
                .apply("year = YEAR(CURDATE() - INTERVAL 1 MONTH) AND month = MONTH(CURDATE() - INTERVAL 1 MONTH)"));
        //获取这些电站的上上月数据，2025年5月获取到2025年3月
        List<SiteDataDO> siteDataDOList2 = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .in(SiteDataDO::getSiteId,siteIds)
                .apply("year = YEAR(CURDATE() - INTERVAL 2 MONTH) AND month = MONTH(CURDATE() - INTERVAL 2 MONTH)"));
        //获取这些电站的去年上月数据，2025年5月获取到2024年4月
        List<SiteDataDO> siteDataDOList3 = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .in(SiteDataDO::getSiteId,siteIds)
                .apply("year = YEAR(CURDATE() - INTERVAL 13 MONTH) AND month = MONTH(CURDATE() - INTERVAL 13 MONTH)"));*/

        // 计算目标年月 - 避免重复调用CURDATE()
        YearMonth current = YearMonth.now();
        YearMonth lastMonth = current.minusMonths(1);
        YearMonth monthBeforeLast = current.minusMonths(2);
        YearMonth lastYearSameMonth = current.minusYears(1).minusMonths(1);

// 准备查询参数
        int lastMonthYear = lastMonth.getYear();
        int lastMonthMonth = lastMonth.getMonthValue();
        int monthBeforeLastYear = monthBeforeLast.getYear();
        int monthBeforeLastMonth = monthBeforeLast.getMonthValue();
        int lastYearSameMonthYear = lastYearSameMonth.getYear();
        int lastYearSameMonthMonth = lastYearSameMonth.getMonthValue();

// 构建单一查询条件
        LambdaQueryWrapper<SiteDataDO> wrapper = new LambdaQueryWrapper<SiteDataDO>()
                .in(SiteDataDO::getSiteId, siteIds)
                .and(qw -> qw
                        // 包含所有目标月份的条件
                        .nested(nqw -> nqw
                                .eq(SiteDataDO::getYear, lastMonthYear)
                                .eq(SiteDataDO::getMonth, lastMonthMonth))
                        .or()
                        .nested(nqw -> nqw
                                .eq(SiteDataDO::getYear, monthBeforeLastYear)
                                .eq(SiteDataDO::getMonth, monthBeforeLastMonth))
                        .or()
                        .nested(nqw -> nqw
                                .eq(SiteDataDO::getYear, lastYearSameMonthYear)
                                .eq(SiteDataDO::getMonth, lastYearSameMonthMonth))
                );

// 执行单一查询获取所有需要的数据
        List<SiteDataDO> allSiteData = siteDataMapper.selectList(wrapper);

// 按年月分组数据
        Map<YearMonth, List<SiteDataDO>> groupedData = allSiteData.stream()
                .collect(Collectors.groupingBy(
                        data -> YearMonth.of(data.getYear(), data.getMonth()),
                        HashMap::new, // 明确指定map类型
                        Collectors.toList()
                ));

// 从分组数据中提取各月份数据
        List<SiteDataDO> siteDataDOList1 = groupedData.getOrDefault(lastMonth, Collections.emptyList());
        List<SiteDataDO> siteDataDOList2 = groupedData.getOrDefault(monthBeforeLast, Collections.emptyList());
        List<SiteDataDO> siteDataDOList3 = groupedData.getOrDefault(lastYearSameMonth, Collections.emptyList());

        //数据求和
        List<SiteDataPageReqVO> siteDataPageReqVOS1 = calculateSummary(siteDataDOList1);

        List<SiteDataPageReqVO> siteDataPageReqVOS2 = calculateSummary(siteDataDOList2);

        List<SiteDataPageReqVO> siteDataPageReqVOS3 = calculateSummary(siteDataDOList3);
        //获取上月的数据，当前月份 - 1（获取上月月份） - 1（获取在list里面的数据，list数组下标从0开始）



        // 去年同月
        SiteDataPageReqVO vo1 = siteDataPageReqVOS1.get(lastMonth.getMonthValue() - 1);

        SiteDataPageReqVO vo2 = siteDataPageReqVOS2.get(monthBeforeLast.getMonthValue() - 1);

        SiteDataPageReqVO vo3 = siteDataPageReqVOS3.get(lastYearSameMonth.getMonthValue() - 1);


        //上月自投毛利和去年同比

        BigDecimal sum1 = vo1.getSelfOpGp();
        BigDecimal sum2 = vo3.getSelfOpGp();

        BigDecimal rate1 = BigDecimal.ZERO;

        if (sum2 == null || sum2.compareTo(BigDecimal.ZERO) == 0) {
            rate1 = sum1;
        }else {
            rate1 = sum1.subtract(sum2).divide(sum2,4,RoundingMode.HALF_UP);
        }

        map.put(1,sum1);
        map.put(2,rate1);


        //上月运能和上上月运能比值
        BigDecimal sum3 = vo1.getSlowCapacity().add(vo1.getFastCapacity());
        BigDecimal sum4 = vo2.getSlowCapacity().add(vo2.getFastCapacity());

        BigDecimal rate2 = BigDecimal.ZERO;

        if (sum4.equals(BigDecimal.ZERO) && sum4 == null || sum4.compareTo(BigDecimal.ZERO) == 0) {
            rate2 = sum3;
        }else{
            rate2 = sum3.subtract(sum4).divide(sum4,4,RoundingMode.HALF_UP);
        }
        //运能数据和比值
        map.put(5,sum3);
        map.put(6,rate2);

        return map;
    }

    @Override
    public Map<Object,Object> dataStatistics(SitePageReqVO sitePageReqVO){
        Map<Object,Object> map = new HashMap<>();

        Map<Object,Object> map1 = averageCapacity(sitePageReqVO);

        Map<Object,Object> map2 = siteService.growthGate(sitePageReqVO);

        Map<Object,Object> map3 = ticketService.growthGate(sitePageReqVO);


        if (map1 != null) {
            map.putAll(map1);
        }if (map2 != null) {
            map.putAll(map2);
        }
        if (map3 != null) {
            map.putAll(map3);
        }

        return map;

    }

    //获取用户能看到的工单数据和电站的一年的总和数据
    @Override
    public Map<Integer, Object> annualData(SitePageReqVO sitePageReqVO){

        Map<Integer, Object> linkedHashMap = new LinkedHashMap<>();

        //获取到电站一年的总和数据
        List<SiteRespVO> siteList = siteService.getSiteList(sitePageReqVO);

        if (siteList == null || siteList.isEmpty()) {
            return null;
        }
        List<Long> siteIds = siteList.stream().map(a -> a.getId()).collect(Collectors.toList());

        Integer year = LocalDateTime.now().getYear();
        //获取这些电站的今年的全部数据
        List<SiteDataDO> siteDataDOList = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .in(SiteDataDO::getSiteId,siteIds)
                .eq(SiteDataDO::getYear,year));

        List<SiteDataPageReqVO> siteDataPageReqVOS = calculateSummary(siteDataDOList);

        SiteDataPageReqVO vo = siteDataPageReqVOS.get(12);

        //自营收入毛利=self_op_gp
        //自营总收益=self_op_all
        //运营成本合计=op_cost_all
        BigDecimal selfOpGp = vo.getSelfOpGp();
        BigDecimal selfOpAll = vo.getSelfOpAll();
        BigDecimal opCostAll = vo.getOpCostAll();
        linkedHashMap.put(3,selfOpGp);
        linkedHashMap.put(4,selfOpAll);
        linkedHashMap.put(5,opCostAll);
        return linkedHashMap;

    }

    //获取上月，前一年，总数据
    public Map<Integer,List<SiteDataDO>> dateGrouping(SitePageReqVO sitePageReqVO) {
        //获取到用户能看到的站点ids
        Map<Integer, List<SiteDataDO>> map = new HashMap<>();
        List<SiteRespVO> siteList = siteService.getSiteList(sitePageReqVO);

        List<Long> siteIds = siteList.stream().map(a -> a.getId()).collect(Collectors.toList());
        //获取这些站点的上月数据，2025年5月获取到2025年4月
        List<SiteDataDO> siteDataDOList1 = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .in(SiteDataDO::getSiteId, siteIds)
                .apply("year = YEAR(CURDATE() - INTERVAL 1 MONTH) AND month = MONTH(CURDATE() - INTERVAL 1 MONTH)"));
        //获取这些站点的去年上月数据，2025年5月获取到2024年4月
        List<SiteDataDO> siteDataDOList2 = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .in(SiteDataDO::getSiteId, siteIds)
                .apply("year = YEAR(CURDATE() - INTERVAL 13 MONTH) AND month = MONTH(CURDATE() - INTERVAL 13 MONTH)"));
        //全部数据
        List<SiteDataDO> siteDataDOList3 = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .in(SiteDataDO::getSiteId, siteIds));

        map.put(1,siteDataDOList1);
        map.put(2,siteDataDOList2);
        map.put(3,siteDataDOList3);

        return map;
    }

    //站点详情的数据获取数据
    public Map<Integer,List<SiteDataDO>> dateGrouping(Long siteId) {
        //获取到用户能看到的站点ids
        Map<Integer, List<SiteDataDO>> map = new HashMap<>();
        //获取这些站点的上月数据，2025年5月获取到2025年4月
        List<SiteDataDO> siteDataDOList1 = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .eq(SiteDataDO::getSiteId, siteId)
                .apply("year = YEAR(CURDATE() - INTERVAL 1 MONTH) AND month = MONTH(CURDATE() - INTERVAL 1 MONTH)"));
        //获取这些站点的去年上月数据，2025年5月获取到2024年4月
        List<SiteDataDO> siteDataDOList2 = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .eq(SiteDataDO::getSiteId, siteId)
                .apply("year = YEAR(CURRENT_DATE) - 1"));
        //全部数据
        List<SiteDataDO> siteDataDOList3 = siteDataMapper.selectList(new LambdaQueryWrapper<SiteDataDO>()
                .eq(SiteDataDO::getSiteId, siteId));

        map.put(1,siteDataDOList1);
        map.put(2,siteDataDOList2);
        map.put(3,siteDataDOList3);

        return map;
    }



    //获取数据 1上月 2上一年 3全部

    @Override
    public Map<Integer,Object> dateGroupingSelect(Integer integer,Long siteId) {
        //获取电站数据和电站工单
        Map<Integer, List<SiteDataDO>> siteDataMap = dateGrouping(siteId);
        Map<Integer, List<TicketDO>> ticketMap = ticketService.dateGrouping(siteId);

        List<SiteDataDO> siteDataDOList = siteDataMap.get(integer);
        List<TicketDO> ticketDOS = ticketMap.get(integer);

        //获取毛利，运能
        List<SiteDataPageReqVO> siteDataPageReqVOS = calculateSummary(siteDataDOList);
        SiteDataPageReqVO vo = new SiteDataPageReqVO();
        if (integer == 1) {
            vo = siteDataPageReqVOS.get(LocalDate.now().getMonthValue() - 2);
        }else {
            vo = siteDataPageReqVOS.get(12);
        }

        BigDecimal selfOpGp = vo.getSelfOpGp();
        BigDecimal add = vo.getSlowCapacity().add(vo.getFastCapacity());
        //工单总量
        int size = ticketDOS.size();
        int i = 0;
        //待处理工单数
        for (TicketDO ticketDO : ticketDOS) {
            if (ticketDO.getTicketStatus() == PENDING.getCode()) {
                i++;
            }
        }
        Map<Integer,Object> map = new LinkedHashMap<>();
        map.put(1,selfOpGp);
        map.put(2,add);
        map.put(3,size);
        map.put(4,i);

        return map;

    }


    public List<MonthlyCostVO> lineChart(SiteDataPageReqVO reqVO){

        List<SiteDataPageReqVO> siteDataPageReqVOS = sumList(reqVO);

        List<MonthlyCostVO> convertedList = new ArrayList<>();
        if(siteDataPageReqVOS != null && !siteDataPageReqVOS.isEmpty()){
            convertedList = ListConverter.convert(siteDataPageReqVOS);
        }

        List<MonthlyCostVO> result = new ArrayList<>();
        //总收入
        result.add(convertedList.get(26));
        //人工成本
        result.add(convertedList.get(14));
        //利润
        result.add(convertedList.get(23));

        return result;
    }







}
